package com.gaogzhen.designPattern.producerConsumer.fullTextSearch;


import com.gaogzhen.designPattern.twoPhraseTermination.AbstractTerminatableThread;

import java.io.*;
import java.text.Normalizer;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @version 1.0
 * @description 附件处理
 * @date 2022-10-27 09:50
 *  模式角色：Producer
 */
public class AttachmentProcessor {
    private final String ATTACHMENT_STORE_BASE_DIR = "/home/attachments/";
    /**
     * 模式角色：Channel
     */
    private final Channel<File> channel = new BlockingQueueChannel<File>(new ArrayBlockingQueue<File>(200)) ;

    /**
     * 模式角色：Consumer
     */
    private final AbstractTerminatableThread indexThread = new AbstractTerminatableThread() {
        @Override
        protected void doRun() throws Exception {
            File file = null;
            file = channel.take();
            try {
                indexFile(file);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                terminationToken.reservations.decrementAndGet();
            }
        }

        private void indexFile(File file) throws InterruptedException {
            // 省略其他代码
            // 模拟生成索引文件的时间消耗
            Random r = new Random();
            TimeUnit.MILLISECONDS.sleep(r.nextInt(100));
        }
    };

    public void init() {
        indexThread.start();
    }

    public void shutdown() {
        indexThread.terminate();
    }

    public void saveAttachment(InputStream in, String documentId, String originalFilename) throws IOException {
        File file = saveAsFile(in, documentId, originalFilename);
        try {
            channel.put(file);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        indexThread.terminationToken.reservations.decrementAndGet();
    }

    private File saveAsFile(InputStream in, String documentId, String originalFilename) throws IOException {
        String dirName = ATTACHMENT_STORE_BASE_DIR + documentId;
        File dir = new File(dirName);
        dir.mkdirs();
        File file = new File(dirName + "/" + Normalizer.normalize(originalFilename, Normalizer.Form.NFC));
        if (!dirName.equals(file.getCanonicalFile().getParent())) {
            throw new SecurityException("Invalid OriginalFilename:" + originalFilename);
        }

        try(BufferedInputStream bis = new BufferedInputStream(in); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));) {
            byte[] buf = new byte[2048];
            int len = -1;
            while ((len = bis.read(buf)) > 0) {
                bos.write(buf, 0, len);
            }
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }
}
